﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Xceed.Silverlight.DataGrid
{
  public abstract class SpinnerBase : Control
  {
    protected SpinnerBase()
    {
    }

    #region HighlightBrush Property

    public static readonly DependencyProperty HighlightBrushProperty = DependencyProperty.Register(
      "HighlightBrush",
      typeof( Brush ),
      typeof( SpinnerBase ),
      new PropertyMetadata( null ) );

    public Brush HighlightBrush
    {
      get
      {
        return ( Brush )this.GetValue( SpinnerBase.HighlightBrushProperty );
      }
      set
      {
        this.SetValue( SpinnerBase.HighlightBrushProperty, value );
      }
    }

    #endregion

    #region ShadowBrush Property

    public static readonly DependencyProperty ShadowBrushProperty = DependencyProperty.Register(
      "ShadowBrush",
      typeof( Brush ),
      typeof( SpinnerBase ),
      new PropertyMetadata( null ) );

    public Brush ShadowBrush
    {
      get
      {
        return ( Brush )this.GetValue( SpinnerBase.ShadowBrushProperty );
      }
      set
      {
        this.SetValue( SpinnerBase.ShadowBrushProperty, value );
      }
    }

    #endregion

    #region Minimum Property

    public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register(
      "Minimum",
      typeof( double ),
      typeof( SpinnerBase ),
      new PropertyMetadata( 0d,
        new PropertyChangedCallback( SpinnerBase.OnMinimumChanged ) ) );

    public double Minimum
    {
      get
      {
        return ( double )this.GetValue( SpinnerBase.MinimumProperty );
      }
      set
      {
        this.SetValue( SpinnerBase.MinimumProperty, value );
      }
    }

    private static void OnMinimumChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e )
    {
      SpinnerBase spinner = sender as SpinnerBase;

      if( spinner == null )
        return;

      spinner.OnMinimumChanged( ( double )e.OldValue, ( double )e.NewValue );
    }

    #endregion

    #region Maximum Property

    public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register(
      "Maximum",
      typeof( double ),
      typeof( SpinnerBase ),
      new PropertyMetadata( 1d,
        new PropertyChangedCallback( SpinnerBase.OnMaximumChanged ) ) );

    public double Maximum
    {
      get
      {
        return ( double )this.GetValue( SpinnerBase.MaximumProperty );
      }
      set
      {
        this.SetValue( SpinnerBase.MaximumProperty, value );
      }
    }

    private static void OnMaximumChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e )
    {
      SpinnerBase spinner = sender as SpinnerBase;

      if( spinner == null )
        return;

      spinner.OnMaximumChanged( ( double )e.OldValue, ( double )e.NewValue );
    }

    #endregion

    #region Value Property

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
      "Value",
      typeof( double ),
      typeof( SpinnerBase ),
      new PropertyMetadata( 0d,
        new PropertyChangedCallback( SpinnerBase.OnValueChanged ) ) );

    public double Value
    {
      get
      {
        return ( double )this.GetValue( SpinnerBase.ValueProperty );
      }
      set
      {
        this.SetValue( SpinnerBase.ValueProperty, value );
      }
    }

    private static void OnValueChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e )
    {
      SpinnerBase spinner = sender as SpinnerBase;

      if( spinner == null )
        return;

      spinner.OnValueChanged( ( double )e.OldValue, ( double )e.NewValue );
    }

    #endregion

    #region Ratio Property

    public static readonly DependencyProperty RatioProperty = DependencyProperty.Register(
      "Ratio",
      typeof( double ),
      typeof( SpinnerBase ),
      new PropertyMetadata( 0d ) );

    public double Ratio
    {
      get
      {
        return ( double )this.GetValue( SpinnerBase.RatioProperty );
      }
    }

    internal void SetRatio( double value )
    {
      this.SetValue( SpinnerBase.RatioProperty, value );
    }

    #endregion

    internal virtual void OnMinimumChanged( double oldValue, double newValue )
    {
      double maximum = this.Maximum;

      if( maximum > newValue )
        this.SetRatio( ( this.Value - newValue ) / ( maximum - newValue ) );
    }

    internal virtual void OnMaximumChanged( double oldValue, double newValue )
    {
      double minimum = this.Minimum;

      if( newValue > minimum )
        this.SetRatio( ( this.Value - minimum ) / ( newValue - minimum ) );
    }

    internal virtual void OnValueChanged( double oldValue, double newValue )
    {
      double minimum = this.Minimum;
      double maximum = this.Maximum;

      if( maximum > minimum )
        this.SetRatio( ( newValue - minimum ) / ( maximum - minimum ) );
    }
  }
}
